package com.xufx.thread.liaoxuefeng.thread12_StampedLock;

import java.util.concurrent.locks.StampedLock;

/**
 * Created by xufx on 2022/1/4 23:40
 * ReadWriteLock解决了多线程同时读，但是只有一个线程写的问题
 * 但是ReadWriteLock是一种悲观锁，要更进一步的提升优化的性能，可以使用新的读写锁：StampedLock
 * StampedLock相比于ReadWriteLock的改进：在读的时候，可以获取写锁进行写入。这是一种乐观锁。
 * StampedLock把读锁细分成了乐观锁和悲观锁，进一步提升了并发效率。
 * 代价：
 *     1. StampedLock是不可重入锁，不能在一个线程中重复获取同一把锁
 *     2. 使用起来代码更加复杂
 *
 * StampedLock还提供了更复杂的将悲观读锁升级为写锁的功能，主要场景是if-then-update的场景：
 * 也就是如果读取的数据满足条件，就返回，如果读取的数据不满足条件，再尝试写
 */
public class Main {
}

class Point{
    private final StampedLock stampedLock = new StampedLock();

    private double x;
    private double y;
    public void  move(double deltaX, double deltaY){
        long stam = stampedLock.writeLock();
        try {
            x += deltaX;
            y += deltaY;
        }finally {
            stampedLock.unlockWrite(stam);
        }
    }

    public double distanceFromOrigin(){
        long stamp = stampedLock.tryOptimisticRead();
        double currentX = x;
        double currentY = y;
        if (!stampedLock.validate(stamp)){
            stamp = stampedLock.readLock();
            try {
                currentX = x;
                currentY = y;
            }finally {
                stampedLock.unlockRead(stamp);
            }
        }
        return Math.sqrt(currentX * currentX  + currentY * currentY);
    }
}
